#include <WiFi.h>                // 引入 WiFi 库，用于连接无线网络
#include <WebServer.h>           // 引入 WebServer 库，创建 HTTP 服务器
#include <ArduinoJson.h>         // 引入 ArduinoJson 库，用于解析 JSON 数据
#include <Adafruit_NeoPixel.h>   // 引入 Adafruit_NeoPixel 库，用于控制 WS2812 LED 灯带

// WiFi 连接信息
const char* ssid = "vivo";       // 设置 WiFi SSID（WiFi 名称）
const char* password = "12345678"; // 设置 WiFi 密码

// LED 相关配置
#define LED_PIN 21      // 定义 WS2812 LED 的数据引脚为 21
#define NUM_LEDS 96     // 定义 LED 的数量为 96
Adafruit_NeoPixel pixels(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800); // 初始化 LED 对象

WebServer server(80); // 创建 Web 服务器，监听端口 80

// 连接 WiFi
void connectWiFi() {
    Serial.print("正在连接 WiFi...");
    WiFi.begin(ssid, password);  // 连接 WiFi
    while (WiFi.status() != WL_CONNECTED) {  // 检查 WiFi 连接状态
        delay(500);  // 每 500ms 检查一次
        Serial.print(".");  // 打印等待指示符
    }
    Serial.println("\nWiFi 连接成功!");  // 连接成功后打印消息
    Serial.print("IP 地址: ");
    Serial.println(WiFi.localIP()); // 打印分配的 IP 地址
}

// 处理情绪请求
void handleEmotion() {
    if (server.hasArg("plain")) {  // 检查是否收到 JSON 数据
        String requestBody = server.arg("plain"); // 获取请求的 JSON 数据
        Serial.println("收到情绪数据: " + requestBody);

        StaticJsonDocument<200> doc;  // 创建 JSON 文档对象
        DeserializationError error = deserializeJson(doc, requestBody);  // 解析 JSON 数据
        if (error) {  // 解析失败
            Serial.println("JSON 解析失败");
            server.send(400, "application/json", "{\"error\":\"JSON 解析失败\"}"); // 返回 400 错误
            return;
        }

        String emotion = doc["emotion"].as<String>(); // 获取 JSON 中的 "emotion" 字段
        Serial.println("检测到的情绪: " + emotion);

        // 根据情绪改变 LED 颜色
        if (emotion == "开心") {
            setLEDColor(0, 255, 0);   // 绿色表示开心
        } else if (emotion == "伤心") {
            setLEDColor(0, 0, 255);   // 蓝色表示伤心
        } else if (emotion == "生气") {
            setLEDColor(255, 0, 0);   // 红色表示生气
        } else {
            setLEDColor(255, 255, 255); // 白色表示默认状态
        }

        server.send(200, "application/json", "{\"status\":\"Emotion received\"}"); // 返回处理成功的状态
    } else {
        server.send(400, "application/json", "{\"error\":\"未收到数据\"}"); // 如果没有收到数据，返回 400 错误
    }
}

// 触发 LED 流动效果
void handleTriggerLED() {
    Serial.println("触发 LED 流动效果!"); // 打印触发消息
    flowLED();  // 调用 LED 流动效果函数
    server.send(200, "application/json", "{\"status\":\"LED triggered\"}"); // 返回处理成功状态
}

// 设置所有 LED 颜色
void setLEDColor(int red, int green, int blue) {
    for (int i = 0; i < NUM_LEDS; i++) { // 遍历所有 LED
        pixels.setPixelColor(i, pixels.Color(red, green, blue)); // 设置 LED 颜色
    }
    pixels.show(); // 显示颜色
}

// 流动 LED 效果
void flowLED() {
    for (int i = NUM_LEDS - 1; i >= 0; i--) { // 倒叙遍历 LED
        pixels.clear(); // 清除所有 LED
        for (int j = 0; j < 5; j++) { // 每次流动 5 颗 LED
            int ledIndex = (i - j + NUM_LEDS) % NUM_LEDS; // 确保索引不越界
            pixels.setPixelColor(ledIndex, pixels.Color(255, 0, 0)); // 设置当前 LED 颜色为红色
        }
        pixels.show(); // 显示 LED 颜色
        delay(5); // 每次更新的延迟时间，可以根据需要调整
    }
}


// 初始化 ESP32
void setup() {
    Serial.begin(115200); // 初始化串口通信，波特率 115200
    pixels.begin(); // 初始化 LED
    setLEDColor(0, 0, 0);  // 关闭所有 LED

    connectWiFi(); // 连接 WiFi

    // 绑定 Web 服务器的路由
    server.on("/emotion", HTTP_POST, handleEmotion); // 处理情绪请求
    server.on("/trigger-led", HTTP_POST, handleTriggerLED); // 处理 LED 触发请求
    server.begin(); // 启动 Web 服务器

    Serial.println("Web 服务器已启动"); // 打印服务器启动信息
}

// 运行服务器
void loop() {
    server.handleClient(); // 处理客户端请求
}
